1 /* 2 Copyright: Marcelo S. N. Mancini (Hipreme|MrcSnm), 2018 - 2021 3 License: [https://creativecommons.org/licenses/by/4.0/|CC BY-4.0 License]. 4 Authors: Marcelo S. N. Mancini 5 6 Copyright Marcelo S. N. Mancini 2018 - 2021. 7 Distributed under the CC BY-4.0 License. 8 (See accompanying file LICENSE.txt or copy at 9 https://creativecommons.org/licenses/by/4.0/ 10 */ 11 12 module hip.api.graphics.color; 13 14 ///This struct is ubyte[4] or uint depending on your usages 15 struct HipColor 16 { 17 @"format" string toString() @nogc const {return "Color($r, $g, $b, $a)"; } 18 union 19 { 20 struct {ubyte r, g, b, a;} 21 ubyte[4] values; 22 uint value; 23 } 24 this(ubyte r, ubyte g, ubyte b){values = [r,g,b,255];} 25 this(ubyte r, ubyte g, ubyte b, ubyte a){values = [r,g,b,a];} 26 this(float r, float g, float b, float a){values = [cast(ubyte)(r*255),cast(ubyte)(g*255),cast(ubyte)(b*255),cast(ubyte)(a*255)];} 27 this(ubyte[4] rgba){values = rgba;} 28 this(uint rgba){values = unpackRGBA(rgba);} 29 30 31 static HipColor alpha(ubyte alpha){return HipColor(255, 255, 255, alpha);} 32 static HipColor alpha(float alpha){return HipColor(255, 255, 255, cast(ubyte)(alpha*255));} 33 static enum white = HipColor(0xffffffff); 34 static enum black = HipColor(0x000000ff); 35 static enum red = HipColor(0xff0000ff); 36 static enum green = HipColor(0x00ff00ff); 37 static enum blue = HipColor(0x0000ffff); 38 static enum yellow = HipColor(0xffff00ff); 39 static enum purple = HipColor(0xff00ffff); 40 static enum teal = HipColor(0x00ffffff); 41 static enum no = HipColor(0x00000000); 42 43 alias values this; 44 45 HipColor lerp(HipColor to, float t) const 46 { 47 float fromT = 1.0 - t; 48 49 ushort nR = cast(ushort)(fromT*r + t*to.r); 50 ushort nG = cast(ushort)(fromT*g + t*to.g); 51 ushort nB = cast(ushort)(fromT*b + t*to.b); 52 ushort nA = cast(ushort)(fromT*a + t*to.a); 53 54 return HipColor( 55 cast(ubyte)(nR > 255 ? 255 : nR), 56 cast(ubyte)(nG > 255 ? 255 : nG), 57 cast(ubyte)(nB > 255 ? 255 : nB), 58 cast(ubyte)(nA > 255 ? 255 : nA), 59 ); 60 } 61 62 } 63 64 65 /** 66 * A struct containing a HipColor and a T which describes what color is in this T. 67 * This is useful for doing color interpolation and gradients. 68 */ 69 struct HipColorStop 70 { 71 HipColor color; 72 float t = 0; 73 } 74 75 /** 76 * 77 * Params: 78 * colorStops = A sorted array of color stops. 79 * t = What is the current T. Ranging from 0 to 1 80 * Returns: The lerped color in the stop. 81 */ 82 HipColor gradientColor(const scope ref HipColorStop[] colorStops, float t) 83 { 84 if(colorStops.length == 0) return HipColor.no; 85 if(t >= 1) return colorStops[$-1].color; 86 for(uint i = 1 ; i < colorStops.length; i++) 87 { 88 if(t > colorStops[i].t) continue; 89 float currLerpT = t / (colorStops[i].t - colorStops[i-1].t); 90 return colorStops[i-1].color.lerp(colorStops[i].color, currLerpT); 91 } 92 return colorStops[$-1].color; 93 } 94 95 /** 96 * This construct is compatible with float[4] when setting a shader variable. 97 */ 98 struct HipColorf 99 { 100 union 101 { 102 struct 103 { 104 float r =0, g = 0, b = 0, a = 0; 105 } 106 float[4] values; 107 } 108 this(HipColor c){values = [cast(float)c.r / 255, cast(float)c.g/255, cast(float)c.b/255, cast(float)c.a/255];} 109 this(float r, float g, float b, float a){values = [r,g,b,a];} 110 ubyte[4] unpackRGBA() 111 { 112 return [cast(ubyte)(r*255), cast(ubyte)(g*255), cast(ubyte)(b*255), cast(ubyte)(a*255)]; 113 } 114 115 uint toInteger() 116 { 117 ubyte red = cast(ubyte)(r*255); 118 ubyte green = cast(ubyte)(g*255); 119 ubyte blue = cast(ubyte)(b*255); 120 ubyte alpha = cast(ubyte)(a*255); 121 return packRGBA(red,green,blue,alpha); 122 } 123 124 static HipColorf fromInt(uint color) 125 { 126 ubyte[4] c = hip.api.graphics.color.unpackRGBA(color); 127 128 return HipColorf( 129 (cast(float)c[0])/255, 130 (cast(float)c[1])/255, 131 (cast(float)c[2])/255, 132 (cast(float)c[3])/255 133 ); 134 } 135 136 auto opAssign(in HipColorf color) 137 { 138 values[] = color.values[]; 139 return this; 140 } 141 142 static enum invalid = HipColorf(-1, -1, -1, -1); 143 static enum white = HipColorf(1,1,1,1); 144 static enum black = HipColorf(0,0,0,1); 145 static enum red = HipColorf(1,0,0,1); 146 static enum green = HipColorf(0,1,0,1); 147 static enum blue = HipColorf(0,0,1,1); 148 static enum yellow = HipColorf(1,1,0,1); 149 static enum purple = HipColorf(1,0,1,1); 150 static enum teal = HipColorf(0,1,1,1); 151 static enum no = HipColorf(0,0,0,0); 152 153 alias values this; 154 } 155 156 uint packRGBA(ubyte r, ubyte g, ubyte b, ubyte a) 157 { 158 return ((r << 24) + (g << 16) + (b << 8) + a); 159 } 160 161 ubyte[4] unpackRGBA(uint rgba) 162 { 163 return 164 [ 165 rgba >> 24, 166 (rgba >> 16) & 255, 167 (rgba >> 8) & 255, 168 rgba & 255 169 ]; 170 } 171 172 pragma(inline, true) 173 { 174 HipColorf color(float[4] c){ return HipColorf(c[0], c[1], c[2], c[3]); } 175 HipColorf color(float r, float g, float b, float a = 1.0){ return HipColorf(r,g,b,a); } 176 177 HipColor color(ubyte r, ubyte g, ubyte b, ubyte a = 255){return HipColor(r,g,b,a);} 178 HipColor color(uint c) 179 { 180 ubyte[4] rgba = unpackRGBA(c); 181 return HipColor(rgba[0], rgba[1], rgba[2], rgba[3]); 182 } 183 }